package xyz.zcxsythenew.app

import android.Manifest
import android.content.Context
import android.os.Bundle
import android.util.AttributeSet
import com.google.android.material.snackbar.Snackbar
import androidx.appcompat.app.AppCompatActivity
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.Button
import android.widget.TextView
import androidx.core.app.ActivityCompat

import kotlinx.android.synthetic.main.activity_main.*
import java.io.InputStream
import java.io.InputStreamReader
import java.net.URL
import java.net.URLEncoder
import java.util.*
import javax.net.ssl.HttpsURLConnection

class MainActivity : AppCompatActivity() {
    var login = false
    private var refreshToken = ""
    var tokenString = ""

    private fun getRefreshTokenInJsonString(json: String) : String {
        var count = 0
        var index = 0
        var startIndex = 0
        var endIndex = 0
        for (i in json) {
            if (i == '\"') {
                count++
                if (count == 13) startIndex = index + 1
                if (count == 14) {
                    endIndex = index
                    break
                }
            }
            index++
        }
        return json.substring(startIndex, endIndex)
    }

    private fun getTokenJsonString(code: String, refresh: Boolean) : String? {
        var connection: HttpsURLConnection? = null
        try {
            val url = URL("https://cas.zcxsythenew.xyz/oauth/token")

            connection = url.openConnection() as HttpsURLConnection
            var csrf : String? = null
            connection.run {
                requestMethod = "GET"
                connect()
                if (responseCode == HttpsURLConnection.HTTP_OK) {
                    csrf = readStream(inputStream)
                }

                disconnect()
            }

            val qs = if (refresh)
                "grant_type=refresh_token&refresh_token=" + URLEncoder.encode(code, "UTF-8")
            else
                "grant_type=authorization_code&code=" + URLEncoder.encode(code, "UTF-8")

            val authenticateByteArray = ("1:1234").toByteArray()
            val authenticateString = Base64.getEncoder().encodeToString(authenticateByteArray)
            connection = url.openConnection() as HttpsURLConnection
            if (csrf != null) {
                connection.run {
                    requestMethod = "POST"
                    setRequestProperty("cookie", "csrfToken=$csrf")
                    setRequestProperty("x-csrf-token", csrf)
                    setRequestProperty("Authorization", "Basic $authenticateString")
                    connect()
                    outputStream.write(qs.toByteArray())
                    if (responseCode == HttpsURLConnection.HTTP_OK) {
                        return readStream(inputStream)
                    }
                }
            }
        } catch (e : Exception) {
            e.printStackTrace()
        } finally {
            connection?.disconnect()
        }
        return null
    }

    private fun readStream(stream: InputStream) : String {
        val reader = InputStreamReader(stream, "UTF-8")
        var str = reader.readText()
        var res = ""
        while (str != "") {
            res += str
            str = reader.readText()
        }
        return res
    }

    fun refresh() {
        Thread(Runnable {
            val res = getTokenJsonString(refreshToken, true)
            if (res != null) {
                refreshToken = getRefreshTokenInJsonString(res)
            }
            login = true
            val sharedPref = this.getPreferences(Context.MODE_PRIVATE)
            with(sharedPref.edit()) {
                putString("token", res)
                commit()
            }
            runOnUiThread {
                val textView = findViewById<TextView>(R.id.textview_first)
                textView.text = res
                val button = findViewById<Button>(R.id.button_first)
                button.isEnabled = true
            }
        }).start()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar)

        if (intent != null && intent.data != null) {
            val uri = intent.data
            if (uri != null) {
                Thread(Runnable {
                    val code = uri.getQueryParameter("code")
                    if (code != null) {
                        val res = getTokenJsonString(code, false)
                        if (res != null) {
                            refreshToken = getRefreshTokenInJsonString(res)
                        }
                        login = true
                        val sharedPref = this.getPreferences(Context.MODE_PRIVATE)
                        with(sharedPref.edit()) {
                            putString("token", res)
                            commit()
                        }
                        runOnUiThread {
                            val textView = findViewById<TextView>(R.id.textview_first)
                            textView.text = res
                            val button = findViewById<Button>(R.id.button_first)
                            button.text = getString(R.string.refresh)
                            button.isEnabled = true
                        }
                    }
                }).start()
            }
        } else {
            val sharedPref = this.getPreferences(Context.MODE_PRIVATE)
            val str = sharedPref.getString("token", "")
            if (str != null && str != "") {
                login = true
                tokenString = str
                refreshToken = getRefreshTokenInJsonString(tokenString)
            }
        }

        fab.setOnClickListener { view ->
            ActivityCompat.requestPermissions(
                this, arrayOf(
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.READ_PHONE_STATE,
                    Manifest.permission.ACCESS_FINE_LOCATION
                ), 0)
            Snackbar.make(view, "Requested Permissions", Snackbar.LENGTH_LONG)
                .setAction("Action", null).show()
        }

        toolbar.setOnMenuItemClickListener {
            login = false
            tokenString = ""
            refreshToken = ""
            val sharedPref = this.getPreferences(Context.MODE_PRIVATE)
            with(sharedPref.edit()) {
                putString("token", "")
                commit()
            }
            val textView = findViewById<TextView>(R.id.textview_first)
            textView.text = getString(R.string.hello_first_fragment)
            val button = findViewById<Button>(R.id.button_first)
            button.text = getString(R.string.login)

            return@setOnMenuItemClickListener true
        }
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        // Inflate the menu; this adds items to the action bar if it is present.
        menuInflater.inflate(R.menu.menu_main, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        return when (item.itemId) {
            R.id.action_settings -> true
            else -> super.onOptionsItemSelected(item)
        }
    }
}